package com.vic.concurrency.completablefuture;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;


public class AsyncCallbackMethodTest {

    public static void main(String[] args) throws Exception {

        thenRun();


    }

    /**
     * thenRun/thenRunAsync
     * 做完第一个任务后，再做第二个任务,第二个任务也没有返回值。
     * thenRun 和thenRunAsync有什么区别呢？」
     * 如果你执行第一个任务的时候，传入了一个自定义线程池：
     *
     * 调用thenRun方法执行第二个任务时，则第二个任务和第一个任务是共用同一个线程池。
     * 调用thenRunAsync执行第二个任务时，则第一个任务使用的是你自己传入的线程池，第二个任务使用的是ForkJoin线程池。
     * 说明: 后面介绍的thenAccept和thenAcceptAsync，thenApply和thenApplyAsync等，它们之间的区别也是这个。
     *
     *
     * @throws InterruptedException
     * @throws ExecutionException
     */
    public static void thenRun() throws InterruptedException, ExecutionException {
        long startTime = System.currentTimeMillis();

        CompletableFuture<Void> cp1 = CompletableFuture.runAsync(() -> {
            try {
                //执行任务A
                System.out.println("执行任务A-开始");
                Thread.sleep(6000);
                System.out.println("执行任务A-结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }

        });

        // 这里等待了 任务A 执行结束后才执行
        CompletableFuture<Void> cp2 = cp1.thenRun(() -> {
            try {
                //执行任务B
                System.out.println("执行任务B-开始");
                Thread.sleep(400);
                System.out.println("执行任务B-结束");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        });

        // get方法测试
        System.out.println(cp2.get());

        //模拟主程序耗时时间
        Thread.sleep(600);
        System.out.println("总共用时" + (System.currentTimeMillis() - startTime) + "ms");
    }

    //运行结果
    /**
     *  null
     *  总共用时1610ms
     */

}
